being.motors package¶
All things motors and motor blocks.
being.motors.blocksDifferent motor blocks.being.motors.controllersCAN motor controllers.being.motors.homingMotor homing.being.motors.motorsHardware motor definitions.
- Available motor blocks are:
DummyMotorLinearMotorRotaryMotorBeltDriveMotorLeadScrewMotorWindupMotor
Submodules¶
being.motors.blocks module¶
Motor blocks.
These blocks represent motors in the being block network. The primary input of a motor block accepts target position values and the primary output outputs the actual position values.

Motor block input and output values.¶
Additionally each motor block offers some helper methods to change its
state during operation (see being.motors.definitions.MotorInterface for
more details).
Motor blocks operate with SI values at their in- and outputs.
Available motor blocks are:
- class DummyMotor(length: float = 0.04, name: Optional[str] = None)[source]¶
Bases:
being.motors.blocks.MotorBlockDummy motor for testing and standalone usage.
- Parameters
length (optional) – Length of dummy motor in meters.
name (optional) – Motor name.
- enable(publish: bool = True)[source]¶
Enable motor (power on).
- Parameters
publish (optional) – If to publish motor changes.
- disable(publish: bool = True)[source]¶
Disable motor (no power).
- Parameters
publish (optional) – If to publish motor changes.
- step(target: float)[source]¶
Step kinematic simulation one step further towards target position.
- Parameters
target – Target position.
- inputs: List[InputBase]¶
Input connections.
- outputs: List[OutputBase]¶
Output connections.
- class CanMotor(nodeId, motor: Union[str, being.motors.motors.Motor], profiled: bool = False, name: Optional[str] = None, multiplier: float = 1.0, length: Optional[float] = None, node: Optional[being.can.cia_402.CiA402Node] = None, objectDictionary=None, network: Optional[being.backends.CanBackend] = None, settings: Optional[Dict[str, Any]] = None, **controllerKwargs)[source]¶
Bases:
being.motors.blocks.MotorBlockMotor blocks for steering a CAN motor.
Set-point values are taken from the blocks position value input (cyclic position mode). If profiled=True use profiled position mode instead. The message input targetPosition can than be used to play new PositionProfiles. In any case the actual position values are streamed via the actualPosition value output.
This class initializes all the necessary components for accessing and configuring a CAN motor:
being.backends.CanBackendnetwork instance (if non has been initialized yet)being.can.cia_402.CiA402NodeCAN node for given node id. Will be passed on to the Controller.being.motors.motors.Motornamed tuple with informations regarding motor hardware and default settings.being.motors.controllers.Controllersubclass instance, depending on motor controller manufacturer.
Components needed for each CAN motor.
![digraph G {
node [shape=box];
subgraph cluster_0 {
label = "CanMotor";
network[label="Network"]
motor[label="Motor"]
subgraph cluster_1 {
label = "Controller";
homing[label="Homing"]
node_[label="Node"]
}
}
}](../_images/graphviz-57523cafe03e2f70128f0a09fae73e6030335fa3.png)
Important
Since most of the time the network will be created implicitly always use this class within
being.resources.manage_resources()context manager.>>> with manage_resources(): ... motor = CanMotor(nodeId=1, 'DC 22')
Otherwise necessary cleanup can not take place and the network will not get disconnected at the end. Motors would stay enabled and the CAN interface could become unreachable on subsequent starts of the program.
This class relays
being.pubsub.PubSubpublications from the underlying controller instance to the outside.>>> def error_callback(errMsg): ... print('Something went wrong', errMsg) ... ... motor.subscribe(MotorEvent.ERROR, error_callback)
- Parameters
nodeId – CANopen node id.
motor – Motor object or motor name.
profiled (optional) – Use profiled position mode instead of cyclic position mode.
name (optional) – Block name.
multiplier (optional) – Multiplier factor which can be used to scale target position / actual position values (only for cyclic position mode).
length (optional) – Motor length which will be shown in the web UI.
node (optional) – CAN node of motor driver / controller. If non given create new one (DI).
objectDictionary (optional) – Object dictionary for CAN node. If will be tried to identified from known EDS files.
network – External CAN network (DI).
settings (optional) – Motor settings. Dict of EDS variables -> Raw value to set. EDS variable with path syntax (slash ‘/’ separator) for nested settings. Will be forwarded to the controller initialization function.
**controllerKwargs – Arbitrary keyword arguments for controller.
- controller: Controller¶
Motor controller.
- enable(publish: bool = False)[source]¶
Enable motor (power on).
- Parameters
publish (optional) – If to publish motor changes.
- disable(publish: bool = True)[source]¶
Disable motor (no power).
- Parameters
publish (optional) – If to publish motor changes.
- to_dict()[source]¶
Convert block to dictionary representation which can be used for dumping as JSON.
- Returns
Block’s dictionary representation.
- inputs: List[InputBase]¶
Input connections.
- outputs: List[OutputBase]¶
Output connections.
- class LinearMotor(nodeId, motor='LM 1247', **kwargs)[source]¶
Bases:
being.motors.blocks.CanMotorDefault linear Faulhaber CAN motor.
- Parameters
nodeId – CANopen node id.
motor (optional) – Motor object or motor name.
**kwargs – Arbitrary keyword arguments for
CanMotor.
- inputs: List[InputBase]¶
Input connections.
- outputs: List[OutputBase]¶
Output connections.
- controller: Controller¶
Motor controller.
- class RotaryMotor(nodeId, motor='DC 22', length=6.283185307179586, **kwargs)[source]¶
Bases:
being.motors.blocks.CanMotorDefault rotary Maxon CAN motor.
- Parameters
nodeId – CANopen node id.
motor (optional) – Motor object or motor name.
length (optional) – Length of rotary motor in radian.
**kwargs – Arbitrary keyword arguments for
CanMotor.
- inputs: List[InputBase]¶
Input connections.
- outputs: List[OutputBase]¶
Output connections.
- controller: Controller¶
Motor controller.
- class BeltDriveMotor(nodeId, length: float, diameter: float, motor='DC 22', **kwargs)[source]¶
Bases:
being.motors.blocks.CanMotorDefault belt drive motor with Maxon controller where the object to be moved is attached on the belt.
- Parameters
nodeId – CANopen node id.
length – Length of belt in meter
diameter – Diameter of pinion belt wheel.
motor (optional) – Motor object or motor name.
**kwargs – Arbitrary keyword arguments for
CanMotor.
- inputs: List[InputBase]¶
Input connections.
- outputs: List[OutputBase]¶
Output connections.
- controller: Controller¶
Motor controller.
- class LeadScrewMotor(nodeId, length: float, threadPitch: float, motor='DC 22', **kwargs)[source]¶
Bases:
being.motors.blocks.CanMotorDefault lead screw motor with Maxon controller.
- Parameters
nodeId – CANopen node id.
length – Total length of the lead screw in meter.
threadPitch – Pitch on lead screw thread (“heigth” per revolution) in meter.
motor (optional) – Motor object or motor name.
**kwargs – Arbitrary keyword arguments for
CanMotor.
- inputs: List[InputBase]¶
Input connections.
- outputs: List[OutputBase]¶
Output connections.
- controller: Controller¶
Motor controller.
- class WindupMotor(nodeId, diameter: float, length: float, motor: str = 'EC 45', outerDiameter: Optional[float] = None, **kwargs)[source]¶
Bases:
being.motors.blocks.CanMotorDefault windup motor with Maxon controller.
Archimedean spiral is used to map angle onto the arc length of the winch.
- Parameters
nodeId – CANopen node id.
diameter – Inner diameter of the spool / coil. Filament is completely unwind. In meters.
length – Length of the filament. Corresponds to the arc length on the coil.
motor – Motor object or motor name.
outerDiameter (optional) – Outer diameter of the spool / coil. This is the diameter when the filament is completely windup. Can be used to compensate of the windup effect of thicker filament. Default is the same as diameter resulting in a circle.
**kwargs – Arbitrary keyword arguments for
CanMotor.
- inputs: List[InputBase]¶
Input connections.
- outputs: List[OutputBase]¶
Output connections.
- controller: Controller¶
Motor controller.
being.motors.controllers module¶
Motor controllers.
Because of ever so small differences between the different motor controller
models there are different subclasses of the main Controller class.
- class Controller(node: being.can.cia_402.CiA402Node, motor: being.motors.motors.Motor, length: float, direction: float = 1.0, settings: Optional[dict] = None, operationMode: being.can.cia_402.OperationMode = OperationMode.CYCLIC_SYNCHRONOUS_POSITION, **homingKwargs)[source]¶
Bases:
being.motors.definitions.MotorInterfaceSemi abstract controller base class.
- Implements general, non-vendor specific, controller functionalities.
Configuring and managing of CANopen node.
Homing
Target position clipping range.
Drives node state switch jobs (for asynchronous state changes).
SI <-> device units conversion.
Relaying EMCY errors.
- Parameters
node – Connected CanOpen node.
motor – Motor definitions / settings.
length – Clipping length in SI units.
direction – Movement direction.
settings – Motor settings.
operationMode – Operation mode for node.
**homingKwargs – Homing parameters.
- EMERGENCY_DESCRIPTIONS: List[tuple]¶
List of (code (int), mask (int), description (str)) tuples with the error informations.
- node: being.can.cia_402.CiA402Node¶
Connected CiA 402 CANopen node.
- motor: being.motors.motors.Motor¶
Associated hardware motor.
- direction¶
Motor direction.
- length¶
Length of motor.
- logger¶
Instance logger.
- position_si_2_device¶
SI position to device units conversion factor.
- velocity_si_2_device¶
SI velocity to device units conversion factor.
- acceleration_si_2_device¶
SI acceleration to device units conversion factor.
- lower¶
Lower clipping value for target position in device units.
- upper¶
Upper clipping value for target position in device units.
- switchJob¶
Ongoing state switching job.
- settings¶
Final motor settings (which got applied to the drive.
- lastState¶
Last receive state of motor controller.
- disable()[source]¶
Disable motor. Schedule a state switching job. Will start by the next call of
Controller.update().
- enable()[source]¶
Enable motor. Schedule a state switching job. Will start by the next call of
Controller.update().
- motor_state() being.motors.definitions.MotorState[source]¶
Return current motor state.
- home()[source]¶
Start homing for this controller. Will start by the next call of
Controller.update().
- homing_state() being.motors.homing.HomingState[source]¶
Return current homing state.
- init_homing(**homingKwargs)[source]¶
Setup homing. Done here and not directly in
Controller.__init__()so that child class can overwrite this behavior.- Parameters
**homingKwargs – Arbitrary keyword arguments for Homing.
- abstract apply_motor_direction(direction: float)[source]¶
Configure direction or orientation of controller / motor.
- format_emcy(emcy: canopen.emcy.EmcyError) str[source]¶
Get vendor specific description of EMCY error.
- play_position_profile(profile: being.motors.definitions.PositionProfile)[source]¶
Play a position profile
PositionProfile.
- play_velocity_profile(profile: being.motors.definitions.VelocityProfile)[source]¶
Play velocity profile
VelocityProfile.
- state_changed(state: being.can.cia_402.State) bool[source]¶
Check if node state changed since last call.
- class Mclm3002(*args, homingMethod: Optional[int] = None, homingDirection: float = 1.0, operationMode: being.can.cia_402.OperationMode = OperationMode.CYCLIC_SYNCHRONOUS_POSITION, **kwargs)[source]¶
Bases:
being.motors.controllers.ControllerFaulhaber MCLM 3002 controller.
This controller does not support the unofficial max current based hard stop homing methods. We monkey patch a CrudeHoming for these cases, which implements the same behavior.
- Parameters
node – Connected CanOpen node.
motor – Motor definitions / settings.
length – Clipping length in SI units.
direction – Movement direction.
settings – Motor settings.
operationMode – Operation mode for node.
**homingKwargs – Homing parameters.
- EMERGENCY_DESCRIPTIONS: List[tuple]¶
List of (code (int), mask (int), description (str)) tuples with the error informations.
- HARD_STOP_HOMING = {-4, -3, -2, -1}¶
- init_homing(**homingKwargs)[source]¶
Setup homing. Done here and not directly in
Controller.__init__()so that child class can overwrite this behavior.- Parameters
**homingKwargs – Arbitrary keyword arguments for Homing.
- apply_motor_direction(direction: float)[source]¶
Configure direction or orientation of controller / motor.
- node: being.can.cia_402.CiA402Node¶
Connected CiA 402 CANopen node.
- motor: being.motors.motors.Motor¶
Associated hardware motor.
- class Epos4(node: being.can.cia_402.CiA402Node, *args, usePositionController: bool = True, recoverRpdoTimeoutError: bool = True, operationMode: being.can.cia_402.OperationMode = OperationMode.CYCLIC_SYNCHRONOUS_POSITION, **kwargs)[source]¶
Bases:
being.motors.controllers.ControllerMaxon EPOS4 controller.
This controllers goes into an error state when RPOD / SYNC messages are not arriving on time -> recoverRpdoTimeoutError which re-enables the motor when the RPOD timeout error occurs.
Also a simple, alternative position controller which sends velocity commands.
Todo
Testing if
firmwareVersion < 0x170h?- Parameters
usePositionController – If True use position controller on EPOS4 with operation mode CYCLIC_SYNCHRONOUS_POSITION. Otherwise simple custom application side position controller working with the CYCLIC_SYNCHRONOUS_VELOCITY.
recoverRpdoTimeoutError – Re-enable drive after a FAULT because of a RPOD timeout error.
- node: being.can.cia_402.CiA402Node¶
Connected CiA 402 CANopen node.
- motor: being.motors.motors.Motor¶
Associated hardware motor.
- EMERGENCY_DESCRIPTIONS: List[tuple]¶
List of (code (int), mask (int), description (str)) tuples with the error informations.
- init_homing(**homingKwargs)[source]¶
Setup homing. Done here and not directly in
Controller.__init__()so that child class can overwrite this behavior.- Parameters
**homingKwargs – Arbitrary keyword arguments for Homing.
- apply_motor_direction(direction: float)[source]¶
Configure direction or orientation of controller / motor.
- static set_all_digital_inputs_to_none(node: canopen.node.remote.RemoteNode)[source]¶
Set all digital inputs of Epos4 controller to none by default. Reason: Because of settings dictionary it is not possible to have two entries. E.g. unset and then set to HOME_SWITCH.
being.motors.definitions module¶
Abstract motor interface.
- class MotorEvent(value)[source]¶
Bases:
enum.EnumMotor / controller events.
- STATE_CHANGED = 1¶
The motor state has changed.
- HOMING_CHANGED = 2¶
The homing state has changed.
- ERROR = 3¶
An error occurred.
- class MotorState(value)[source]¶
Bases:
enum.EnumSimplified motor state.
- FAULT = 0¶
Motor in fault state.
- DISABLED = 1¶
Motor is disabled.
- ENABLED = 2¶
Motor is enabled and working normally.
- class PositionProfile(position: float, velocity: Optional[float] = None, acceleration: Optional[float] = None)[source]¶
Bases:
NamedTuplePosition profile segment.
Units are assumed to be SI. Controller has to convert to device units.
Create new instance of PositionProfile(position, velocity, acceleration)
- class VelocityProfile(velocity: float, acceleration: Optional[float] = None)[source]¶
Bases:
NamedTupleVelocity profile segment.
Units are assumed to be SI. Controller has to convert to device units.
Create new instance of VelocityProfile(velocity, acceleration)
- class MotorInterface[source]¶
Bases:
being.pubsub.PubSub,abc.ABCBase class for motor like things and what they have to provide.
- Parameters
events – Supported events.
- abstract disable(publish: bool = True)[source]¶
Disable motor (no power).
- Parameters
publish (optional) – If to publish motor changes.
- abstract enable(publish: bool = True)[source]¶
Enable motor (power on).
- Parameters
publish (optional) – If to publish motor changes.
- abstract motor_state() being.motors.definitions.MotorState[source]¶
Return current motor state.
- abstract home()[source]¶
Start homing routine for this motor. Has then to be driven via the update() method.
- abstract homing_state() being.motors.homing.HomingState[source]¶
Return current homing state.
being.motors.homing module¶
Homing procedures and definitions.
Todo
Documentation. Waiting for feature branch merge.
- class HomingState(value)[source]¶
Bases:
enum.EnumPossible homing states.
- FAILED = 0¶
- UNHOMED = 1¶
- ONGOING = 2¶
- HOMED = 3¶
- class CiA402Homing(node, timeout=10.0, **kwargs)[source]¶
Bases:
being.motors.homing.HomingBaseCiA 402 by the book.
- set_operation_mode(op: being.can.cia_402.OperationMode)[source]¶
Set operation mode of node. No questions asked…
- class CrudeHoming(node, minWidth, currentLimit, timeout=10.0, **kwargs)[source]¶
Bases:
being.motors.homing.CiA402HomingCrude hard stop homing for Faulhaber linear motors.
- Parameters
speed – Speed for homing in device units.
being.motors.motors module¶
Effective hardware motors. Represents the effective motor itself. Different default settings.
- class DeviceUnits(position: float = 1.0, velocity: float = 1.0, acceleration: float = 1.0)[source]¶
Bases:
NamedTupleMotor device units factor. Gear factor not included.
Todo
Should this move to to
being.motors.controllers.Controller? Is it motor or controller dependent?Create new instance of DeviceUnits(position, velocity, acceleration)
- class Motor(manufacturer: str, name: str, length: float = inf, units: being.motors.motors.DeviceUnits = DeviceUnits(position=1.0, velocity=1.0, acceleration=1.0), gear: fractions.Fraction = Fraction(1, 1), defaultSettings: dict = {})[source]¶
Bases:
NamedTupleHardware motor.
Definitions, settings for different hardware motors.
Create new instance of Motor(manufacturer, name, length, units, gear, defaultSettings)
- units: being.motors.motors.DeviceUnits¶
Device units.
- gear: fractions.Fraction¶
Gear ratio.
- orify(things: Sequence) str[source]¶
Comma separate sequence with final ‘or’.
Example
>>> orify(['a', 'b', 'c']) 'a, b or c'
- get_motor(name: str) being.motors.motors.Motor[source]¶
Lookup motor by name.
- Parameters
name – Motor name. Can be lowercase and spaces get deleted for easy lookup.
- Returns
Motor informations.
- Raises
KeyError – If motor could not be found.
Example
>>> motor = get_motor('LM 1247') ... motor.name 'LM 1247'
>>> get_motor('R2D2') KeyError: 'Unknown motor R2D2! Try one of LM1247, LM0830, LM1483, LM2070, EC45 or DC22'
being.motors.vendor module¶
Vendor specific definitions / helpers for the different controllers. Error codes, emergency descriptions, supported homing method.
- class MaxonMotorType(value)[source]¶
Bases:
enum.IntEnumMaxon motor types.
- PHASE_MODULATED_DC_MOTOR = 1¶
- SINUSOIDAL_PM_BL_MOTOR = 10¶
- TRAPEZOIDAL_PM_BL_MOTOR = 11¶
- class MaxonSensorsConfiguration(sensorType3, sensorType2, sensorType1)[source]¶
Bases:
NamedTupleCreate new instance of MaxonSensorsConfiguration(sensorType3, sensorType2, sensorType1)
- class MaxonControlStructure(mountingPositionSensor3: int = 0, mountingPositionSensor2: int = 0, mountingPositionSensor1: int = 0, auxiliarySensor: int = 0, mainSensor: int = 1, processValueReference: int = 0, gear: int = 0, positionControlStructure: int = 1, velocityControlStructure: int = 1, currentControlStructure: int = 1)[source]¶
Bases:
NamedTupleMaxon EPOS4 Axis configuration Control structure.
Create new instance of MaxonControlStructure(mountingPositionSensor3, mountingPositionSensor2, mountingPositionSensor1, auxiliarySensor, mainSensor, processValueReference, gear, positionControlStructure, velocityControlStructure, currentControlStructure)
- class MaxonDigitalIncrementalEncoderType(method: int = 0, direction: int = 0, index: int = 1)[source]¶
Bases:
NamedTupleDefines the configuration of the digital incremental encoder 1.
Create new instance of MaxonDigitalIncrementalEncoderType(method, direction, index)
- class MaxonDigitalInput(value)[source]¶
Bases:
enum.IntEnumValues for Configuration of digital inputs.
- NONE = 255¶
- QUICK_STOP = 28¶
- DRIVE_ENABLE = 27¶
- POSITIVE_LIMIT_SWITCH_WITHOUT_ERRORS = 25¶
- NEGATIVE_LIMIT_SWITCH_WITHOUT_ERRORS = 24¶
- GENERAL_PURPOSE_H = 23¶
- GENERAL_PURPOSE_G = 22¶
- GENERAL_PURPOSE_F = 21¶
- GENERAL_PURPOSE_E = 20¶
- GENERAL_PURPOSE_D = 19¶
- GENERAL_PURPOSE_C = 18¶
- GENERAL_PURPOSE_B = 17¶
- GENERAL_PURPOSE_A = 16¶
- HOME_SWITCH = 2¶
- POSITIVE_LIMIT_SWITCH = 1¶
- NEGATIVE_LIMIT_SWITCH = 0¶